/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#ifndef CGL_HeightMap_H_
#define CGL_HeightMap_H_

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <GL/glut.h>
#include <vector>
#include <list>
#include "ownutils.h"

#define X_AX                    0
#define Y_AX                    1
#define Z_AX                    2

#ifndef MIN
#define MIN(a,b) ((a>b)?b:a)
#endif
#ifndef MAX
#define MAX(a,b) ((a<b)?b:a)
#endif
using namespace std;

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/// GRAPH VECTOR STUFF DEFINITIONS
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/**
 * Struct representing a single point in 3D space
 */
typedef struct __gspot // HarHarHar ;)
{
		float x;
		float y;
		float z;
} TGraphPoint, TGraphVector;

TGraphVector operator - (const TGraphVector &a, const TGraphVector &b);
TGraphVector operator + (const TGraphVector &a, const TGraphVector &b);

bool operator == (const TGraphVector &a, const TGraphVector &b);

typedef vector<TGraphPoint> TGraphPointVector;
typedef vector<TGraphPoint>::iterator TGraphPointVectorIterator;

/**
 * Structure representing a single Triangle in 3D space.
 */
typedef struct __gtriangle
{
		TGraphPoint a;
		TGraphPoint b;
		TGraphPoint c;
} TGraphTriangle;
  
typedef vector<TGraphTriangle> TGraphTriangleVector;
typedef vector<TGraphTriangle>::iterator TGraphTriangleVectorIterator;

typedef struct __gcolor
{
		float red;
		float green;
		float blue;
		float other;
} TGraphColor;

typedef vector<TGraphColor> TGraphColorVector;
typedef vector<TGraphColor>::iterator TGraphColorVectorIterator;
TGraphVector hm_crossProductVector(const TGraphVector &v1, 
																	 const TGraphVector &v2);
TGraphVector hm_normalizeVector(const TGraphVector &v);
TGraphVector hm_calculateFaceNormal(const TGraphTriangle &t);
TGraphVector hm_calculateVertexNormal(const TGraphPoint &vertex, 
																			const TGraphPointVector &near);
float hm_calculatePointDistance( float *p1, float *p2 );
TGraphVector hm_constructNormalForHeightMapPoint(float **heightMap,int x, int z,
				float xR, float yR,
				float zR,int xdim, int zdim);


/*
 * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
 * Input:  imageFile - name of .rgb to read
 *         intFormat - internal texture format to use, or number of components
 * Return:  GL_TRUE if success, GL_FALSE if error.
 */
GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat);
GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
											 GLenum *format );

class CGLHeightMap{
		public:
				/**
				* Constructor
				* Takes the Height map size and resolution as input
				* Optionally one can give texture for the heightmap as a filename
				* @p _Nx Number of cells in x dir
				* @p _Ny Number of cells in y dir
				* @p reso Resolution = size of one cell in meters
				* @p doTexturing flag to set the texturing on
				* @p *texturename filename of the texture file
				*/
				CGLHeightMap(int _Nx, int _Ny, float reso, 
																	 bool doTexturing=false, 
																	 const char *texturename="groundtexture.rgb");
				~CGLHeightMap();
				void setData(float *hm);
				bool generateDisplayList();
				void draw();
		private:
				int Nx;
				int Ny;
				float resolution;
				bool doTexture;
				bool texLoaded;
				int displayListID;
				ownMutexHandle dataMutex;
				bool newData;
				
				TGraphPointVector normalVectorList;
				TGraphVector n;
				float **heightMap;
				TGraphVector **normalMap;
				
				GLuint	texture[1];
				char texname[50];
				void texUnbind(); ///< Unbind the texture
				void texBind();   ///< Bind the texture
				void texLoad();   ///< Load the texture
				
				void setMaterialParameters();
				
				void allocate();
				void freeAll();
};




#endif


